using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Musc.MuscProxy;

namespace msgExchange
{
    public static class CEncodingHelper
    {
        public static String decode(string s) 
        {
            if (string.IsNullOrEmpty(s))
            {
                return "";
            }
            StringBuilder sb = new StringBuilder(s.Length);
            char[] chars = s.ToCharArray();
            for (int i = 0; i < chars.Length ; i++) {
                char c = chars[i];
                if (c == '\\' && chars[i + 1] == 'u') {
                    char cc = (char)0;
                    for (int j = 0; j < 4; j++) {
                        char ch = Char.ToLower(chars[i + 2 + j]);
                        if ('0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f') {
                            int vv2=Convert.ToInt32(ch.ToString(), 16);
                            cc |= (char)( (char )vv2<< (3 - j) * 4);
                        } else {
                            cc =(char) 0;
                            break;
                        }
                    }
                    if (cc > 0) {
                        i += 5;
                        sb.Append(cc);
                        continue;
                    }
                }
                sb.Append(c);
            }
            return sb.ToString();
        }

    }

    public class AreaOwnership
    {
        string data_ = "";
        public AreaOwnership(string d)
        {
            data_ = d;
        }

        public static string getSubString(string src, string b, string e)
        {
            string v = "";
            int idx = src.IndexOf(b);
            if (idx > 0)
            {
                int idxEnd= src.IndexOf( e, idx +b.Length );
                if (idxEnd > 0)
                {
                    if (idxEnd - (idx + b.Length) > 0)
                    {
                        v = src.Substring(idx   + b.Length, idxEnd - (idx   + b.Length));
                    }
                }
            }

            return v;
        }

        public string getCity()
        {
            try
            {
                return CEncodingHelper.decode(AreaOwnership.getSubString(data_, "\"city\":\"", "\""));
            }
            catch { }

            return "";
        }

        public string getISP()
        {
            try
            {            
                return CEncodingHelper.decode(AreaOwnership.getSubString(data_, "\"isp\":\"", "\"")); 
            }
            catch { }

            return "";       
        }

    };

    public class CAOSItem
    {
        public CAOSItem(string guid,string ip){guestUID_=guid;ip_=ip;}
        public string guestUID_="";
        public string ip_ = "";
        public string isp_ = "";
        public string addr_="";
        public int cmdID_ = 0;

    };

    public class CTaskList
    {
        private List<CAOSItem> lstTask_ = new List<CAOSItem>();
        private object lock_ = new object();

        public void Add(CAOSItem pdi)
        {
            lock (lock_)
            {
                bool foundV = false;
                for (int j = 0; j < lstTask_.Count; j++)
                {
                    if (lstTask_[j].guestUID_ == pdi.guestUID_)
                    {
                        foundV = true;
                        break;
                    }

                }
                if (!foundV)
                {
                    lstTask_.Add(pdi);
                }

            }

        }

        public void Clear()
        {
            lock (lock_)
            {
                lstTask_.Clear();
            }
        }
        public CAOSItem Remove(int cmdid)
        {
            CAOSItem cPdiFound = null;
            lock (lock_)
            {
                for (int j = 0; j < lstTask_.Count; j++)
                {
                    if (lstTask_[j].cmdID_ == cmdid)
                    {
                        cPdiFound = lstTask_[j];
                        lstTask_.RemoveAt(j);
                        break;
                    }
                }
            }
            return cPdiFound;
        }
        public CAOSItem GetAt(int idx)
        {
            CAOSItem cPdiFound = null;
            lock (lock_)
            {
                if (verifyIndex(idx))
                {
                    cPdiFound = lstTask_[idx];
                }
            }

            return cPdiFound;
        }

        public CAOSItem PopTop()
        {
            CAOSItem cPdiFound = null;
            lock (lock_)
            {
                if (lstTask_.Count > 0)
                {
                    cPdiFound = lstTask_[0];
                    lstTask_.RemoveAt(0);
                }


            }

            return cPdiFound;
        }

        protected bool verifyIndex(int idx)
        {
            return (idx >= 0 && idx < lstTask_.Count);
        }


        public int Size()
        {
            lock (lock_)
            {
                return lstTask_.Count;
            }
        }
    
    }

    public class AreaOwnerShipManager : TaskThread
    {
        protected const int WAITTIMEOUT_THREAD = 2 * 1000;
        private ManualResetEvent eventNonEmpty_ = new ManualResetEvent(false);

        public CEngineProxy engineProxy_ = null;
        protected CTaskList  taskList_= new CTaskList();
        protected CTaskList resultList_ = new CTaskList();

        public AreaOwnerShipManager() { }
        public void addTask(CAOSItem a)
        {
            taskList_.Add(a);
        }
        public CAOSItem parseResult(int cmdid, string data)
        {
            AreaOwnership aos = new AreaOwnership(data);
            CAOSItem aosTemp = resultList_.Remove(cmdid);
            if (null != aosTemp)
            {
                aosTemp.addr_ = aos.getCity();
                aosTemp.isp_ = aos.getISP();

                return aosTemp;
            }

            return null;
        }

        protected override void ThreadRountine()
        {
            CAOSItem item = null;
            while (!isInterrupted_)
            {
                eventNonEmpty_.WaitOne(WAITTIMEOUT_THREAD, false);
                {
                    item = taskList_.GetAt(0);
                    if (null != item)
                    {
                        if (engineProxy_.isLogon())
                        {
                            item.cmdID_ = engineProxy_.sendServiceComandEx(1121, "chkip", item.ip_);
                            if (item.cmdID_ > 0)
                            {
                                resultList_.Add(item);
                            }
                        }
                        taskList_.PopTop();
                    }
                }
            }
        }


    }

}
